package com.fengwk.user.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fengwk.support.code.Sequence;
import com.fengwk.support.exception.BaseException;
import com.fengwk.support.page.PageInfo;
import com.fengwk.support.util.CollectionUtils;
import com.fengwk.user.dao.UsRoleDao;
import com.fengwk.user.dao.UsRolePermissionLinkDao;
import com.fengwk.user.dao.UsUserRoleLinkDao;
import com.fengwk.user.face.entity.UsRole;
import com.fengwk.user.face.entity.UsRolePermissionLink;
import com.fengwk.user.face.entity.UsUserRoleLink;
import com.fengwk.user.face.model.Role;
import com.fengwk.user.service.RoleService;

@Service
public class RoleServiceImpl implements RoleService {

	@Autowired
	private UsRoleDao usRoleDao;
	@Autowired
	private UsUserRoleLinkDao usUserRoleLinkDao;
	@Autowired
	private UsRolePermissionLinkDao usRolePermissionLinkDao;
	
	@Transactional
	@Override
	public Role saveRole(String role, String description) {
		UsRole usRole = usRoleDao.findByRole(role);
		if (usRole != null)
			throw new BaseException("角色[" + role + "]已存在");
		usRole = new UsRole();
		usRole.setRoleId(Sequence.next());
		usRole.setRole(role);
		usRole.setDescription(description);
		usRoleDao.insert(usRole);
		return usRoleToRole(usRole);
	}

	@Transactional
	@Override
	public Role removeRole(Long roleId) {
		UsRole usRole = findUsRole(roleId);
		if (usRole != null) {
			usUserRoleLinkDao.deleteByRoleId(roleId);
			usRolePermissionLinkDao.deleteByRoleId(roleId);
			usRoleDao.deleteByRoleId(roleId);
		}
		return usRoleToRole(usRole);
	}

	@Transactional
	@Override
	public Role updateRole(Long roleId, String role, String description) {
		UsRole usRole = findUsRole(roleId);
		if (usRole != null) {
			if (role != null)
				usRole.setRole(role);
			if (description != null)
				usRole.setDescription(description);
			usRoleDao.updateByRoleId(usRole);
		}
		return usRoleToRole(usRole);
	}
	
	@Transactional
	@Override
	public void synPermission(Long roleId, Collection<Long> permissionIds) {
		usRolePermissionLinkDao.deleteByRoleId(roleId);
		addPermission(roleId, permissionIds);
	}
	
	@Transactional
	@Override
	public void addPermission(Long roleId, Collection<Long> permissionIds) {
		List<UsRolePermissionLink> usRolePermissionLinkList = CollectionUtils.toListWithTypeConvert(
				permissionIds, permissionId -> {
					UsRolePermissionLink usRolePermissionLink = new UsRolePermissionLink();
					usRolePermissionLink.setRecordId(Sequence.next());
					usRolePermissionLink.setRoleId(roleId);
					usRolePermissionLink.setPermissionId(permissionId);
					return usRolePermissionLink;
				});
		if (CollectionUtils.isNotBlank(usRolePermissionLinkList)) {
			usRolePermissionLinkDao.batchInsert(usRolePermissionLinkList);
		}
	}

	@Transactional
	@Override
	public void removePermission(Long roleId, Collection<Long> permissionIds) {
		usRolePermissionLinkDao.deleteByRoleIdAndPermissionIds(roleId, permissionIds);
	}
	
	@Override
	public List<Role> listRoleByUserId(Long userId) {
		List<Role> roleList = new ArrayList<>();
		List<UsUserRoleLink> usUserRoleLinkList = usUserRoleLinkDao.queryByUserId(userId);
		if (CollectionUtils.isNotBlank(usUserRoleLinkList)) {
			List<Long> roleIdList = CollectionUtils.toListWithTypeConvert(
					usUserRoleLinkList, usUserRoleLink -> usUserRoleLink.getRoleId());
			List<UsRole> usRoleList = usRoleDao.queryInRoleIds(roleIdList);
			roleList = usRolesToRoleList(usRoleList);
		}
		return roleList;
	}
	
	@Override
	public PageInfo<Role> pageRole(int pageNum, int pageSize) {
		PageInfo<Role> pageInfo = new PageInfo<>(pageNum, pageSize);
		List<UsRole> ssRoleList = usRoleDao.page(pageInfo.queryStartRow(), pageInfo.queryPageSize());
		pageInfo.setTotal(usRoleDao.countAll());
		pageInfo.setList(usRolesToRoleList(ssRoleList));
		return pageInfo;
	}
	
	private UsRole findUsRole(Long roleId) {
		UsRole usRole = usRoleDao.findByRoleId(roleId);
		if (usRole == null) 
			throw new BaseException("角色[" + roleId + "]不存在");
		return usRole;
	}
	
	private Role usRoleToRole(UsRole usRole) {
		return CollectionUtils.getFirstFromList(
				usRolesToRoleList(CollectionUtils.buildList(usRole, true)));
	}
	
	private List<Role> usRolesToRoleList(Collection<UsRole> usRoles) {
		return CollectionUtils.toListWithTypeConvert(
				usRoles, usRole -> {
					Role role = new Role();
					role.setRoleId(usRole.getRoleId());
					role.setRole(usRole.getRole());
					role.setDescription(usRole.getDescription());
					return role;
				});
	}

}
